﻿//using System.Collections;
//using System.Collections.Generic;
//using System.IO;
//using System;
//using UnityEngine;
//using ILRuntime.Runtime.Enviorment;
//using System.Reflection;
//using ILRuntime.CLR.TypeSystem;
//using ILRuntime.CLR.Method;

//public class ILRManager : BaseManager {
//    //ILRuntime的入口,AppDomain是一个应用程序域，每个AppDomain都是一个独立的沙盒
//    ILRuntime.Runtime.Enviorment.AppDomain appdomain;
//	//是否需要记录日志(true会加载pdb，加大性能消耗和内存占用）
//    public bool released = false;
//    void Start()
//    {
//        //StartCoroutine(LoadHotFixAssembly());
//    }
//    IEnumerator LoadHotFixAssembly()
//    {
//        appdomain = new ILRuntime.Runtime.Enviorment.AppDomain();
//        //正常项目中从其他地方下载dll，或者打包在AssetBundle中读取
//        string dllPath ="";
//        //Debug.Log(dllPath);
//        //E:/U3dProj/borderExtension/BorderExpansion/borderExpansionProj/Library/ScriptAssemblies/Assembly-CSharp.dll
//#if UNITY_ANDROID //在编辑器里 如果切换到了安卓平台，则也会执行这里的代码
//        //WWW www = new WWW(Application.streamingAssetsPath + "/Assembly-CSharp.dll");
//        WWW www = new WWW(MainConfigPath.PersistentDataPath() + "/Assembly-CSharp.dll");
//#else
//        WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/Assembly-CSharp.dll");
//        //WWW www = new WWW(MainConfigPath.StreamingAssetsPath() + "/Assembly-CSharp.dll");
//#endif

//        while (!www.isDone)
//            yield return null;
//        if (!string.IsNullOrEmpty(www.error))
//            MainUtil.LogError(www.error);
//        byte[] dll = www.bytes;
//        www.Dispose();

//        if (!released)
//        {
//            //PDB文件是调试数据库，如需要在日志中显示报错的行号，则必须提供PDB文件，不过由于会额外耗用内存，正式发布时要将PDB去掉，下面LoadAssembly的时候pdb传null即可
//#if UNITY_ANDROID
//                    //www = new WWW(Application.streamingAssetsPath + "/Assembly-CSharp.pdb");
//                    www = new WWW(Application.dataPath.Replace("Assets", "") + "Library/ScriptAssemblies/Assembly-CSharp.pdb");
//#else
//            //www = new WWW("file:///" + Application.streamingAssetsPath + "/Assembly-CSharp.pdb");
//            www = new WWW("file:///" + MainConfigPath.pdbPath);
//#endif
//            while (!www.isDone)
//                yield return null;
//            if (!string.IsNullOrEmpty(www.error))
//                UnityEngine.Debug.LogError(www.error);
//            byte[] pdb = www.bytes;
//            using (System.IO.MemoryStream fs = new MemoryStream(dll))
//            {
//                using (System.IO.MemoryStream p = new MemoryStream(pdb))
//                {
//                    appdomain.LoadAssembly(fs, p, new Mono.Cecil.Pdb.PdbReaderProvider());
//                }
//            }
//        }
//        else {
//            using (System.IO.MemoryStream fs = new MemoryStream(dll))
//            {
//                appdomain.LoadAssembly(fs, null, null);
//            }
//        }
//        InitializeILRuntime();
//    }

//    //这里做一些ILRuntime的注册,尽量减少跨域继承
//    void InitializeILRuntime()
//    {
//        // //注册继承外部类或接口的适配器
//        // appdomain.RegisterCrossBindingAdaptor(new CoroutineAdaptor());
//        // appdomain.RegisterCrossBindingAdaptor(new InheriteIDispoableAdaptor());
//        // //热更dll里面尽量不要写继承自monobehaviour的方法，这种方法应该作为工具类放在主工程里面，不会去多次修改的
//        // appdomain.RegisterCrossBindingAdaptor(new MonoBehaviourAdapter());
//        //
//        // //注册委托适配器:将要传出给ilruntime外部使用的委托实例类型，同一个参数组合的委托，只需要注册一次
//        // //尽量使用action,func系统自带万用委托类型
//        // appdomain.DelegateManager.RegisterMethodDelegate<GameObject>();
//        // appdomain.DelegateManager.RegisterMethodDelegate<UnityEngine.Object>();
//        // appdomain.DelegateManager.RegisterMethodDelegate<UnityEngine.Object, Dictionary<string, object>, Action<UnityEngine.Object>>();

//        //注册委托转换器:对于不是系统自带的上述委托类型，需要些转换器
//        //eg: delegate bool SomeFunction(int a, float b);
//        //appdomain.DelegateManager.RegisterDelegateConvertor<SomeFunction>((action) =>
//        //{
//        //    return new SomeFunction((a, b) =>
//        //    {
//        //        return ((Func<int, float, bool>)action)(a, b);
//        //    });
//        //});

//        //ILRuntimeCLRBinding脚本下自动绑定代码，用于将unity主工程下的方法给dll内的方法调用
//        ILRuntime.Runtime.Generated.CLRBindings.Initialize(appdomain);

//        OnILRuntimeInitialized();
//    }

//    void OnILRuntimeInitialized()
//    {
//        //先将热更逻辑从主工程移除，通过加载dll的流程来执行ilr启动
//        appdomain.Invoke("App", "Start", null, null);
//    }

//    public void OnHotFixLoaded()
//    {
//        //入口方法调用，从dll中获取启动脚本启动游戏，然后开始逻辑的运行
//        if (MainFacade.Instance.main.loadDllType == Main.LoadDLLType.ILRuntimeHotFix)
//        {
//            MainUtil.Log("ILR启动游戏");
//            StartCoroutine(LoadHotFixAssembly());

//            //foreach (System.Type type in Assembly.LoadFile(MainConfigPath.dllPath).GetTypes())
//            //{
//            //    if (type.Name.ToLower().Contains(facade.main.typeStr.ToLower()))
//            //    {
//            //        Debug.Log(type.Name);
//            //    }
//            //}

//            //IType itype = appdomain.LoadedTypes["App"];
//            ////根据方法名称和参数个数获取方法
//            //IMethod method = itype.GetMethod("Start", 0);

//            //appdomain.Invoke(method, itype, null);

//            //object obj = appdomain.Instantiate("App");
//            //appdomain.Invoke("App", "Start", obj, null);
//        }
//        else {
//            //foreach (System.Type type in Assembly.LoadFile(MainConfigPath.dllPath).GetTypes())
//            //{
//            //    if (type.Name.ToLower().Contains("inheriteidispoable"))
//            //    {
//            //        Debug.Log(type.Name);
//            //    }
//            //}
//            MainUtil.Log("Reflection启动游戏");
//#if UNITY_ANDROID && !UNITY_EDITOR 
//            StartCoroutine(LoadDll());
//#else
//            //loadfrom:加载目标dll及其引用的dll  loadfile:只加载目标dll
//            Assembly hotFixDll = Assembly.LoadFrom(MainConfigPath.PersistentDataPath_IO() + "Assembly-CSharp.dll");//MainConfigPath.dllPath
//            MainUtil.Log(hotFixDll.ToString());
//            hotFixDll.GetType("App").GetMethod("Start").Invoke(null, null);
//#endif
//        }
//    }

//    IEnumerator LoadDll() {
//        WWW www = new WWW(MainConfigPath.PersistentDataPath() + "/Assembly-CSharp.dll");
//        yield return www;
//        if(www.error != null)
//        {
//            MainUtil.Log("assembly DLL加载出错："+ www.error);
//        }
//        if (www.isDone)
//        {
//            MainUtil.Log("assembly DLL载完毕");
//            //先把DLL以TextAsset类型取出来,再把bytes给Assembly.Load方法读取准备进入反射操作
//            Assembly hotFixDll = Assembly.Load(www.bytes);
//            hotFixDll.GetType("App").GetMethod("Start").Invoke(null, null);
//        }
//    }
//}
